const app = getApp();
const YmodemSimple = require('../../utils/ymodemSimple.js');
const ConfigManager = require('../../utils/configManager.js');

Page({
  data: {
    mcuType: '',           // 控制器型号
    currentVersion: '',    // 当前版本
    cloudVersion: '',      // 云端固件版本号
    binFileName: '',       // bin文件名
    downloadProgress: 0,   // 下载进度
    uploadProgress: 0,     // 上传进度
    status: 'idle',        // idle, checking, downloading, uploading, completed, error
    statusText: '等待连接控制器',
    firmwareSize: 0,       // 固件大小（字节）
    firmwareSizeKB: '0',   // 固件大小（KB，格式化后的字符串）
    firmwareData: null,    // 固件数据
    hasUpdate: false,      // 是否有更新
    receiveQueue: [],      // 接收数据队列（模拟C++的tcRcvQueue）
  },

  onLoad() {
    this.configManager = new ConfigManager();
    this.init();
  },

  onShow() {
    // 每次显示页面时检查连接状态
    if (app.data.connected && app.data.LOGOK) {
      this.checkControllerInfo();
    }
  },

  /**
   * 初始化
   */
  async init() {
    wx.showLoading({ title: '加载配置中...' });

    try {
      // 预加载配置文件
      await this.configManager.loadConfig();
      wx.hideLoading();
      
      // 检查控制器信息
      this.checkControllerInfo();

    } catch (error) {
      wx.hideLoading();
      wx.showToast({
        title: '加载配置失败',
        icon: 'none'
      });
      console.error('[OTA] 初始化失败:', error);
    }
  },

  /**
   * 检查控制器信息
   */
  async checkControllerInfo() {
    // 检查蓝牙连接
    if (!app.data.connected) {
      this.setData({
        statusText: '请先连接控制器'
      });
      
      wx.showModal({
        title: '未连接控制器',
        content: '请先在"实时"页面连接控制器',
        confirmText: '去连接',
        success: (res) => {
          if (res.confirm) {
            wx.switchTab({ url: '/pages/index/index' });
          }
        }
      });
      return;
    }

    // 检查是否登录
    if (!app.data.LOGOK) {
      this.setData({
        statusText: '请等待登录完成'
      });
      return;
    }

    // 等待控制器型号读取
    if (!app.data.ptype) {
      wx.showLoading({ title: '读取控制器信息...' });
      
      for (let i = 0; i < 50; i++) {
        await this.sleep(100);
        if (app.data.ptype) break;
      }
      
      wx.hideLoading();
    }

    // 显示控制器信息
    const mcuType = app.data.ptype || '未知';
    const currentVersion = app.data.mcuswver || '未知';

    this.setData({
      mcuType: mcuType,
      currentVersion: currentVersion,
      statusText: '准备升级'
    });

    if (!app.data.ptype) {
      wx.showToast({
        title: '无法获取控制器型号',
        icon: 'none'
      });
      return;
    }

    // 自动检查配置
    this.checkFirmware();
  },

  /**
   * 检查固件信息
   */
  async checkFirmware() {
    this.setData({
      status: 'checking',
      statusText: '正在查询固件信息...'
    });

    try {
      const config = await this.configManager.getControllerConfig(this.data.mcuType);
      
      if (!config) {
        throw new Error(`不支持的控制器型号: ${this.data.mcuType}`);
      }

      if (!config.binFile) {
        throw new Error('该型号暂无固件文件');
      }

      console.log('[OTA] 固件配置:', config);

      this.setData({
        binFileName: config.binFile,
        cloudVersion: config.version || '未知',
        status: 'idle',
        statusText: '准备升级',
        hasUpdate: true
      });

      // 显示提示信息
      const versionInfo = config.version ? `v${config.version}` : '';
      wx.showToast({
        title: `发现新版本${versionInfo}`,
        icon: 'success',
        duration: 2000
      });

    } catch (error) {
      console.error('[OTA] 检查固件失败:', error);
      
      this.setData({
        status: 'error',
        statusText: error.message,
        hasUpdate: false
      });

      wx.showToast({
        title: error.message,
        icon: 'none',
        duration: 3000
      });
    }
  },

  /**
   * 手动检查
   */
  onCheckFirmware() {
    console.log('[OTA] 点击了"检查固件"按钮');
    this.checkFirmware();
  },

  /**
   * 点击开始升级按钮（调试用）
   */
  onStartOTA() {
    console.log('[OTA] 点击了"开始升级"按钮');
    this.startOTA();
  },

  /**
   * 开始OTA升级
   */
  async startOTA() {
    console.log('[OTA] ========== 开始OTA升级流程 ==========');
    console.log('[OTA] 当前数据:', {
      mcuType: this.data.mcuType,
      currentVersion: this.data.currentVersion,
      cloudVersion: this.data.cloudVersion,
      binFileName: this.data.binFileName,
      hasUpdate: this.data.hasUpdate,
      connected: app.data.connected,
      LOGOK: app.data.LOGOK
    });

    // 检查蓝牙连接状态
    if (!app.data.connected) {
      console.error('[OTA] 蓝牙未连接');
      wx.showToast({
        title: '请先连接控制器',
        icon: 'none'
      });
      return;
    }

    if (!app.data.LOGOK) {
      console.error('[OTA] 未登录');
      wx.showToast({
        title: '请等待登录完成',
        icon: 'none'
      });
      return;
    }

    console.log('[OTA] 显示安全提示对话框...');
    // 安全检查
    const confirmed = await this.showSafetyWarning();
    console.log('[OTA] 用户确认结果:', confirmed);
    if (!confirmed) {
      console.log('[OTA] 用户取消升级');
      return;
    }

    try {
      console.log('[OTA] ===== 步骤1: 下载固件 =====');
      // 步骤1: 下载固件
      await this.downloadFirmware();
      console.log('[OTA] 固件下载完成');

      console.log('[OTA] ===== 步骤2: 进入Bootloader =====');
      // 步骤2: 进入Bootloader
      await this.enterBootloader();
      console.log('[OTA] Bootloader进入成功');

      console.log('[OTA] ===== 步骤3: 上传固件 =====');
      // 步骤3: 上传固件
      await this.uploadFirmware();
      console.log('[OTA] 固件上传完成');

      console.log('[OTA] ========== OTA升级流程完成 ==========');

    } catch (error) {
      console.error('[OTA] ========== 升级失败 ==========');
      console.error('[OTA] 错误详情:', error);
      console.error('[OTA] 错误栈:', error.stack);
      
      this.setData({
        status: 'error',
        statusText: '升级失败: ' + error.message
      });

      wx.showModal({
        title: '升级失败',
        content: error.message + '\n\n请重试或联系技术支持',
        showCancel: false
      });
    }
  },

  /**
   * 安全提示
   */
  showSafetyWarning() {
    console.log('[OTA] 正在显示安全警告对话框...');
    const versionInfo = this.data.cloudVersion ? ` → v${this.data.cloudVersion}` : '';
    return new Promise((resolve) => {
      wx.showModal({
        title: '⚠️ 固件升级确认',
        content: `当前版本: ${this.data.currentVersion}${versionInfo}\n\n升级过程约需2-5分钟，请确保：\n• 电池电量充足（≥30%）\n• 不要关闭小程序\n• 不要断开蓝牙连接\n• 不要关闭控制器电源\n\n升级失败可能导致设备无法使用！`,
        confirmText: '开始升级',
        confirmColor: '#e64340',
        success: (res) => {
          console.log('[OTA] 对话框回调 - 用户点击了:', res.confirm ? '确定' : '取消');
          console.log('[OTA] 对话框返回值:', res);
          resolve(res.confirm);
        },
        fail: (err) => {
          console.error('[OTA] 对话框显示失败:', err);
          resolve(false);
        },
        complete: () => {
          console.log('[OTA] 对话框完成');
        }
      });
    });
  },

  /**
   * 下载固件
   */
  async downloadFirmware() {
    console.log('[OTA] 开始下载固件...');
    
    this.setData({
      status: 'downloading',
      statusText: '正在下载固件...',
      downloadProgress: 0
    });

    console.log('[OTA] 获取控制器配置:', this.data.mcuType);
    const config = await this.configManager.getControllerConfig(this.data.mcuType);
    console.log('[OTA] 配置信息:', config);
    console.log('[OTA] 下载地址:', config.binUrl);
    
    // 下载bin文件
    console.log('[OTA] 开始下载文件...');
    const tempPath = await this.configManager.downloadFile(
      config.binUrl,
      (progress) => {
        const sizeBytes = progress.totalBytesExpectedToWrite || 0;
        console.log('[OTA] 下载进度:', progress.progress + '%', '/', (sizeBytes / 1024).toFixed(2) + 'KB');
        this.setData({
          downloadProgress: progress.progress || 0,
          firmwareSize: sizeBytes,
          firmwareSizeKB: (sizeBytes / 1024).toFixed(2)
        });
      }
    );
    console.log('[OTA] 文件下载完成，临时路径:', tempPath);

    // 读取文件内容
    console.log('[OTA] 开始读取文件内容...');
    const firmwareData = await this.configManager.readFile(tempPath, 'binary');
    console.log('[OTA] 文件读取完成，大小:', firmwareData.length, '字节');

    // 验证固件
    console.log('[OTA] 开始验证固件...');
    if (!this.validateFirmware(firmwareData)) {
      console.error('[OTA] 固件验证失败');
      throw new Error('固件文件校验失败');
    }
    console.log('[OTA] 固件验证通过');

    this.setData({
      firmwareData: firmwareData,
      firmwareSize: firmwareData.length,
      firmwareSizeKB: (firmwareData.length / 1024).toFixed(2),
      downloadProgress: 100,
      statusText: '固件下载完成'
    });

    console.log('[OTA] 固件下载完成, 大小:', firmwareData.length);
    
    await this.sleep(1000);
  },

  /**
   * 验证固件
   */
  validateFirmware(data) {
    if (!data || data.length === 0) {
      console.error('[OTA] 固件文件为空');
      return false;
    }

    if (data.length < 10 * 1024) {
      console.error('[OTA] 固件文件过小:', data.length);
      return false;
    }

    if (data.length > 5 * 1024 * 1024) {
      console.error('[OTA] 固件文件过大:', data.length);
      return false;
    }

    console.log('[OTA] 固件验证通过');
    return true;
  },

  /**
   * 进入Bootloader模式
   */
  async enterBootloader() {
    console.log('[OTA] 进入Bootloader模式...');
    
    wx.showLoading({ 
      title: '进入升级模式...',
      mask: true 
    });

    this.setData({
      statusText: '正在进入升级模式...'
    });

    try {
      // 步骤1：发送"WrflRqst"字符串
      console.log('[OTA] 步骤1: 发送WrflRqst命令');
      const wrflRqstStr = "WrflRqst";
      const wrflRqstBytes = new Uint8Array(8);
      for (let i = 0; i < 8; i++) {
        wrflRqstBytes[i] = wrflRqstStr.charCodeAt(i);
      }
      console.log('[OTA] WrflRqst字节:', Array.from(wrflRqstBytes));
      
      // 复制到发送缓冲区
      for (let i = 0; i < 8; i++) {
        app.data.BLE_Txbuff[i] = wrflRqstBytes[i];
      }
      app.data.Txbuffid = 0;
      app.writeBLECharacteristicValue();

      console.log('[OTA] 发送WrflRqst命令');
      await this.sleep(1000);

      // 步骤2：发送节点地址（默认0x31，即字符'1'）
      app.data.BLE_Txbuff[0] = 0x31; // 节点地址，根据实际情况修改
      app.data.Txbuffid = 0;
      app.writeBLECharacteristicValue2boot();

      console.log('[OTA] 发送节点地址');

      // 步骤3：等待接收'C'字符（表示Bootloader准备好）
      let bootloaderReady = false;
      let cPosition = -1;
      
      for (let i = 0; i < 50; i++) { // 最多等待5秒
        await this.sleep(100);
        
        // 检查是否收到'C'字符
        if (app.data.Rebuffi > 0) {
          console.log('[OTA] 接收到数据，长度:', app.data.Rebuffi, '内容:', Array.from(app.data.BLE_Rebuff.slice(0, app.data.Rebuffi)));
          
          for (let j = 0; j < app.data.Rebuffi; j++) {
            if (app.data.BLE_Rebuff[j] === 0x43) { // 'C'
              bootloaderReady = true;
              cPosition = j;
              console.log('[OTA] 在位置', j, '发现C字符，Bootloader已准备好');
              break;
            }
          }
          
          // 重要：不要清空缓冲区！保留'C'字符给Ymodem使用
          // 只清除'C'之前的无用数据
          if (bootloaderReady && cPosition > 0) {
            console.log('[OTA] 清除C之前的', cPosition, '个字节');
            for (let k = 0; k < app.data.Rebuffi - cPosition; k++) {
              app.data.BLE_Rebuff[k] = app.data.BLE_Rebuff[k + cPosition];
            }
            app.data.Rebuffi = app.data.Rebuffi - cPosition;
            console.log('[OTA] 保留缓冲区数据，长度:', app.data.Rebuffi);
          }
        }
        
        if (bootloaderReady) break;
      }

      wx.hideLoading();

      if (!bootloaderReady) {
        console.error('[OTA] 等待Bootloader超时，接收缓冲区:', app.data.Rebuffi);
        throw new Error('Bootloader未响应，请重试');
      }

      console.log('[OTA] 成功进入Bootloader模式，缓冲区中保留了C字符');

    } catch (error) {
      wx.hideLoading();
      throw new Error('进入升级模式失败: ' + error.message);
    }
  },

  /**
   * 上传固件
   */
  async uploadFirmware() {
    console.log('[OTA] 准备上传固件...');
    
    // 清空所有缓冲区（包括可能混入的AT指令响应）
    console.log('[OTA] 清空接收缓冲区，当前长度:', app.data.Rebuffi);
    app.data.Rebuffi = 0;
    for (let i = 0; i < app.data.BLE_Rebuff.length; i++) {
      app.data.BLE_Rebuff[i] = 0;
    }
    
    // 初始化接收队列（完全清空，等待控制器重新发送'C'）
    this.setData({
      receiveQueue: [],
      status: 'uploading',
      statusText: '正在上传固件...',
      uploadProgress: 0
    });
    
    console.log('[OTA] 接收缓冲区已清空，等待控制器发送C信号...');
    
    // 等待一小段时间，让控制器稳定
    await this.sleep(200);

    const ymodem = new YmodemSimple();

    // 蓝牙发送函数（分包发送，确保数据完整性）
    const writeFunc = async (data) => {
      console.log('[OTA] 发送数据，长度:', data.length, '前10字节:', Array.from(data.slice(0, 10)));
      
      const MTU = 20; // 蓝牙MTU限制
      
      for (let i = 0; i < data.length; i += MTU) {
        const chunkSize = Math.min(MTU, data.length - i);
        
        // 创建新的ArrayBuffer和Uint8Array（与正常写入保持一致）
        const buffer = new ArrayBuffer(chunkSize);
        const view = new Uint8Array(buffer);
        for (let j = 0; j < chunkSize; j++) {
          view[j] = data[i + j];
        }
        
        console.log('[OTA] 发送分包', Math.floor(i/MTU) + 1, '/', Math.ceil(data.length/MTU), 
                    '长度:', chunkSize, '数据:', Array.from(view));
        
        await new Promise((resolve, reject) => {
          wx.writeBLECharacteristicValue({
            deviceId: app._deviceId,
            serviceId: app._serviceId,
            characteristicId: app._characteristicId,
            value: buffer,  // 直接使用ArrayBuffer（与正常写入一致）
            success: resolve,
            fail: reject
          });
        });
        
        // ✅ 增加延迟：让控制器有足够时间接收和处理
        await this.sleep(20); // 从10ms增加到20ms
      }
      
      // ✅ 发送完成后增加更多等待时间，让控制器重组数据包、计算CRC、发送ACK
      await this.sleep(500); // 从200ms增加到500ms
      console.log('[OTA] 数据包发送完成，等待控制器处理（已等待500ms）...');
    };

    // 蓝牙接收函数（返回队列中的所有数据）
    // 参数 clearQueue: 如果为true，返回数据后清空队列
    const readFunc = async (clearQueue = false) => {
      // 先将缓冲区的新数据加入队列
      if (app.data.Rebuffi > 0) {
        for (let i = 0; i < app.data.Rebuffi; i++) {
          this.data.receiveQueue.push(app.data.BLE_Rebuff[i]);
        }
        console.log('[OTA] readFunc加入新数据', app.data.Rebuffi, '字节，队列总长度:', this.data.receiveQueue.length);
        app.data.Rebuffi = 0;
      }
      
      // 返回队列中的所有数据
      if (this.data.receiveQueue.length > 0) {
        const data = new Uint8Array(this.data.receiveQueue);
        console.log('[OTA] readFunc返回', data.length, '字节:', Array.from(data), clearQueue ? '(清空队列)' : '(保留队列)');
        
        // 如果需要清空队列
        if (clearQueue) {
          this.data.receiveQueue = [];
        }
        
        return data;
      }
      
      return null;
    };

    // 进度回调
    const onProgress = (percentage) => {
      this.setData({
        uploadProgress: percentage,
        statusText: `上传进度: ${percentage}%`
      });
    };

    try {
      const success = await ymodem.sendFile(
        this.data.firmwareData,
        this.data.binFileName,
        writeFunc,
        readFunc,
        onProgress
      );

      if (success) {
        this.setData({
          status: 'completed',
          statusText: '升级完成！',
          uploadProgress: 100
        });

        wx.showModal({
          title: '✅ 升级成功',
          content: '固件已成功写入！控制器将自动重启...',
          showCancel: false,
          success: () => {
            setTimeout(() => {
              wx.switchTab({ url: '/pages/index/index' });
            }, 3000);
          }
        });
      }

    } catch (error) {
      throw new Error('固件上传失败: ' + error.message);
    }
  },

  /**
   * 延迟函数
   */
  sleep(ms) {
    return new Promise(resolve => setTimeout(resolve, ms));
  }
});

